package org.developer.websocketserver.client;

import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;

import java.io.File;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Arrays;

@Slf4j
public class ByteDemoClient {

    private static final String BASE_URL = "ws://localhost:9999?userId=abc123";
    // 音频文件路径
    private static final String AUDIO_PATH = "";

    // 每次发送的数据大小 1280 字节
    private static final int CHUNCKED_SIZE = 1280;

    public static void main(String[] args) throws Exception {

        URI url = new URI(BASE_URL);
        CustomWebSocketClient client = new CustomWebSocketClient(url);
        client.connect();

        while (!client.getReadyState().equals(ReadyState.OPEN)) {

            log.info("\t[连接中]");
            Thread.sleep(1000);
        }

        //发送音频,分片发送
        byte[] bytes = new byte[CHUNCKED_SIZE];
        try (RandomAccessFile raf = new RandomAccessFile(AUDIO_PATH, "r")) {

            int len = -1;
            long lastTs = 0;

//            //发送文件长度
//            File file = new File(AUDIO_PATH);
//            String fileDataLength = String.valueOf(file.length());
//            byte[] lengthBytes = fileDataLength.getBytes();
//            send(client,lengthBytes);

            while ((len = raf.read(bytes)) != -1) {

                if (len < CHUNCKED_SIZE) {
                    send(client, bytes = Arrays.copyOfRange(bytes, 0, len));
                    break;
                }

                long curTs = System.currentTimeMillis();
                if (lastTs == 0) {

                    lastTs = System.currentTimeMillis();
                } else {
                    long s = curTs - lastTs;
                    if (s < 40) {
                        log.info("error time interval: " + s + " ms");
                    }
                }
                send(client, bytes);
                //每隔 40 毫秒发送一次数据
                Thread.sleep(40);
            }

//            // 发送结束标识
//            send(client, "{\"end\": true}".getBytes());
//            log.info("\t发送结束标识完成");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送字节数据
     * @param client websocket客户端
     * @param bytes 字节数组
     */
    public static void send(WebSocketClient client, byte[] bytes) {

        if (client.isClosed()) {
            throw new RuntimeException("client connect closed");
        }

        client.send(bytes);
    }

    static class CustomWebSocketClient extends WebSocketClient {

        public CustomWebSocketClient(URI serverUri) {

            super(serverUri);
        }

        @Override
        public void onOpen(ServerHandshake handshakedata) {

            log.info("\t[连接成功]");

        }

        @Override
        public void onMessage(String msg) {

            //握手成功
            log.info("msg={}\n",msg);
        }

        @Override
        public void onClose(int code, String reason, boolean remote) {

            log.info("\t[连接关闭],code={},reason={}",code,reason);
        }

        @Override
        public void onError(Exception ex) {

            log.error("\t[连接发生错误]={}",ex.getMessage());
            ex.printStackTrace();
        }

        @Override
        public void onMessage(ByteBuffer bytes) {

            try {
                log.info("服务端返回={}", new String(bytes.array(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
    }
}
